#include "Game.h"
//#include "Scene.h"

#include "YGDict.h"

//#define ANDROID_TEST

#ifdef ANDROID_TEST
#	include <GLES/gl.h>
#endif

using namespace YoghurtGum;

RenderMethod* g_Renderer = NULL;

int centerX = 0;
int centerY = 0;
int screen_width = 0;
int screen_height = 0;
int scissor_sx = 0;
int scissor_sy = 0;
int scissor_ex = 0;
int scissor_ey = 0;

struct Stripe
{
	float dirX, dirY;
	float start;
	float length;
};

#define STRIPES_AMOUNT		32
#define STRIPES_START		32
#define STRIPES_END			160
#define STRIPES_MAXLENGTH	16

Stripe stripes[STRIPES_AMOUNT];
float degX[60];
float degY[60];

Player* player;

Game* Game::Configure()
{
	Root::GetSingleton().SetProperty(Root::PROP_WINDOWTITLE, "Galaxians");

	Root::GetSingleton().InstallRenderer("RenderMethodDirectDraw");
	Root::GetSingleton().InstallRenderer("RenderMethodOpenGLES");

	yg::Dict test;

	int width = 640;
	int height = 480;

	test.Set("x", width);
	test.Set("y", height);

	const int* map_w = test.Get<int>("x");
	const int* map_h = test.Get<int>("y");

	return new Galaxians;
}

#ifdef ANDROID_TEST

inline GLfixed GlIntToFixed(int x) { return x << 16; }

GLfixed vx = GlIntToFixed(230);
GLfixed vy = GlIntToFixed(310);
GLfixed g_TestVertices[12] = {
	0, 0,    vx, 0,    vx, vy,
	0, 0,    0, vy,    vx, vy
};

#endif

void Galaxians::Init()
{
	g_Renderer = Root::GetSingleton().GetRenderer();

	/*screen_width = Device::Get().GetWidth();
	screen_height = Device::Get().GetHeight();*/

	screen_width = 240;
	screen_height = 320;

	scissor_sx = (Device::Get().GetWidth() - screen_width) / 2;
	//scissor_sx = 0;
	scissor_sy = (Device::Get().GetHeight() - screen_height) / 2;
	//scissor_sy = 0;

	scissor_ex = 240;
	scissor_ey = 320;

	Log::GetSingleton().Print(
		"Scissor (%i, %i)(%i, %i)", 
		scissor_sx, scissor_sy, 
		//scissor_x + screen_width, scissor_y + screen_height
		scissor_ex, scissor_ey
	);

	centerX = screen_width / 2;
	centerY = screen_height / 2;

	m_SurfStars = g_Renderer->CreateSurface(screen_width, screen_height);

	scene_main_menu = new Scene();
	scene_game = new Scene();

	// start on the main menu
	scene_current = scene_main_menu;

	g_Renderer->LoadImage("media/Viper_Mark_II.bmp", "ship",    Color(1.f, 0.f, 1.f));
	g_Renderer->LoadImage("media/alien.bmp",         "alien",   Color(1.f, 0.f, 1.f));
	g_Renderer->LoadImage("media/bat_ball.bmp",      "bullet",  Color(1.f, 0.f, 1.f));

	m_Player = new Player();
	m_Player->Restart(screen_width, screen_height);
	scene_current->AddObject(m_Player);

	for (int i = 0; i < 60; i++)
	{
		degX[i] = Math::CosDeg(i * 6.f);
		degY[i] = Math::SinDeg(i * 6.f);
	}

	for (int i = 0; i < STRIPES_AMOUNT; i++)
	{
		int dir = (int)Math::Random(0, 59);
		stripes[i].dirX = degX[dir];
		stripes[i].dirY = degY[dir];

		stripes[i].start = Math::Random(STRIPES_START, STRIPES_END);
		stripes[i].length = 2.f;
	}

	int width = 48;
	int offset = (screen_width - (width * 5)) / 2 + 8;

	for (int i = 0; i < 5; ++i)
	{
		m_Alien[i]     = new Alien((float)(offset + (i * width)), 4.f);
		m_Alien[i + 5] = new Alien((float)(offset + (i * width)), 4.f + 48.f);

		/*scene_current->AddObject(new Alien(offset + (i * width), 4));
		scene_current->AddObject(new Alien(offset + (i * width), 4 + 48));*/

		scene_current->AddObject(m_Alien[i]);
		scene_current->AddObject(m_Alien[i + 5]);
	}
	//scene_current->AddObject(new Alien(8, 4));

}

void Galaxians::Resize(int a_Width, int a_Height)
{
	centerX = a_Width / 2;
	centerY = a_Height / 2;

	m_SurfStars->Resize(a_Width, a_Height);

	m_Player->Restart(screen_width, screen_height);

	int width = 48;
	int offset = (screen_width - (width * 5)) / 2 + 8;

	for (int i = 0; i < 5; ++i)
	{
		m_Alien[i]->SetPosition(offset + (i * width), 4);
		m_Alien[i + 5]->SetPosition(offset + (i * width), 4 + 48);
	}
}

void Galaxians::Update()
{
	scene_current->Update();

	for (int i = 0; i < STRIPES_AMOUNT; i++)
	{
		stripes[i].start += 1.5f;
		if (stripes[i].start > STRIPES_END) 
		{ 
			int dir = (int)Math::Random(0, 59);
			stripes[i].dirX = degX[dir];
			stripes[i].dirY = degY[dir];

			stripes[i].start = STRIPES_START; 
		}

		stripes[i].length = 1 + ((stripes[i].start - STRIPES_START) / (STRIPES_END - STRIPES_START)) * STRIPES_MAXLENGTH;
	}

	if (TouchScreen::Get().Pressed() || Keyboard::Get().Pressed(YGK_OK))
	{
		Root::GetSingleton().CloseDown();
	}
}

void Galaxians::Render()
{

#ifdef ANDROID_TEST

	glClearColor(1.f, 0.f, 0.f, 1.f);
	glClear(GL_COLOR_BUFFER_BIT);

	glEnable(GL_SCISSOR_TEST);
	glScissor(
		scissor_sx, scissor_sy, 
		scissor_ex, scissor_ey
	);
	glViewport(
		scissor_sx, scissor_sy, 
		scissor_ex, scissor_ey
	);

	/*glClearColor(0.f, 1.f, 0.f, 1.f);
	glClear(GL_COLOR_BUFFER_BIT);

	glDisable(GL_SCISSOR_TEST);*/

	/*glClearColor(1.f, 0.f, 0.f, 1.f);
	glClear(GL_COLOR_BUFFER_BIT);

	glEnable(GL_SCISSOR_TEST);
	glScissor(
		scissor_sx, scissor_sy, 
		scissor_ex, scissor_ey * 2
	);
	glViewport(
		scissor_sx, scissor_sy, 
		scissor_ex, scissor_ey
	);*/

	glClearColor(0.f, 1.f, 0.f, 1.f);
	glClear(GL_COLOR_BUFFER_BIT);

	glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		glOrthox(
			0, GlIntToFixed(screen_width), 
			GlIntToFixed(screen_height), 0,
			GlIntToFixed(-1), GlIntToFixed(1)
		);
	glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();

	/*glColor4f(0.f, 0.f, 1.f, 1.f);
	glEnableClientState(GL_VERTEX_ARRAY);
		glVertexPointer(2, GL_FIXED, 0, g_TestVertices);
		glDrawArrays(GL_TRIANGLES, 0, 6);
	glDisableClientState(GL_VERTEX_ARRAY);*/

#endif

	m_SurfStars->Lock();

	m_SurfStars->Fill(Color(0.f, 0.f, 0.f));

	for (int i = 0; i < STRIPES_AMOUNT; i++)
	{
		m_SurfStars->Line(
			centerX + (stripes[i].dirX * stripes[i].start),
			centerY + (stripes[i].dirY * stripes[i].start),
			centerX + (stripes[i].dirX * (stripes[i].start + stripes[i].length)),
			centerY + (stripes[i].dirY * (stripes[i].start + stripes[i].length)),
			Color(1.f, 1.f, 0.f)
		);
	}

	m_SurfStars->Unlock();

	m_SurfStars->Draw(0, 0);

	// draw the scene graphics
	scene_current->Render();

#ifdef ANDROID_TEST

	glDisable(GL_SCISSOR_TEST);

#endif

}